home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c-part2 / 13668 < prev    next >
Encoding:
Text File  |  1996-08-05  |  4.8 KB  |  141 lines

  1. Path: mayne.ugrad.cs.ubc.ca!not-for-mail
  2. From: c2a192@ugrad.cs.ubc.ca (Kazimir Kylheku)
  3. Newsgroups: comp.lang.c
  4. Subject: Re: String assignments, please help (beginner)
  5. Date: 9 Apr 1996 11:14:39 -0700
  6. Organization: Computer Science, University of B.C., Vancouver, B.C., Canada
  7. Message-ID: <4ke9efINNnv@mayne.ugrad.cs.ubc.ca>
  8. References: <4ke05g$27q@soap.news.pipex.net>
  9. NNTP-Posting-Host: mayne.ugrad.cs.ubc.ca
  10.  
  11. In article <4ke05g$27q@soap.news.pipex.net>, Tone <tone@dial.pipex.com> wrote:
  12. >I've just been learning C for the last few weeks and have come across
  13. >a problem with assigning strings, which I will detail below.
  14. >(Sorry the posting is so long, I'm just trying to make sure you know
  15. >exactly what my problem is):
  16. >
  17. >I was originally informed that the following was valid:
  18. >
  19. >    char string1[30];
  20. >    string1 = "Test string";
  21.  
  22. Nope. Whoever told you likely believed that arrays are pointers, which is
  23. buffoonery.
  24.  
  25. >This gave me an error on the second line although when declaring I am
  26. >able to use:
  27. >
  28. >    char string1[30] = "Test string";
  29.  
  30. That's because it's not an assignment. It is an initializer. An initializer is
  31. a special syntactic unit that is part of a declaration. C allows string
  32. literals to act as initializers for character arrays. Assingments are
  33. statements, but initializers don't necessarily generate code (when they are
  34. static).
  35.  
  36. >I have then read up and found the following info elsewhere (quote):
  37. >
  38. >    a = "This is a string.";
  39. >    is only possible if a is a char pointer.
  40.  
  41. Yes. The value of a string literal expression is a pointer to an unnamed piece
  42. of storage which houses a string. This pointer may be assigned to a char *
  43. type. There is one exception to this. If you initialize a static char array
  44. with a string literal, no unnamed storage is necessarily created. Instead, the
  45. static array is created such that it initially contains the given data. (At
  46. least this is how it is often _implemented_).
  47.  
  48.  
  49. >so I arrived at the following:
  50. >
  51. >    char *string1[30];
  52. >    *string1 = "Test string";
  53. >
  54. >This compiles okay and gives the desired result in the small program I
  55. >was writing.
  56.  
  57. That is incorrect. The expression "string1" refers to an array object, but
  58. produces a value that is a pointer to the first element according to the
  59. special array semantics of C. When you write *string1 the effect is the same as
  60. though you had written *(&string1[0]).  This expression is an lvalue that
  61. refers to a char object by dereferencing string1[0] pointer. Not only is this
  62. not assignment compatible with "Test string", but it deferences a pointer that
  63. has not been initialized.
  64.  
  65. >However, I have since found the following information (quote):
  66. >
  67. >    int *c;
  68. >    *c = 4;
  69.  
  70. It is undefined behavior because c is not initialized.
  71.  
  72. >    can and probably will give some unexpected and unwelcome results!
  73. >    As the value of c is random, the memory-address to which 4 is
  74. >    assigned is random, too. This means that you could change basically
  75. >    any location in the memory, including machine code.
  76.  
  77. This rationale should be taken with a grain of salt. The truth is that anything
  78. can happen, based on what the implementation does with such undefined behavior.
  79.  
  80. >I am assuming that these "unexpected results" mentioned above will
  81. >also apply to the code I have written.
  82.  
  83. Well, not exactly. The pointer to the "Test string" literal will probably be
  84. converted to an integer according to some implementation-defined mapping, and
  85. then forced into a char.
  86.  
  87. >The only other way I know of assigning a string is to create a loop
  88. >(e.g. a "for" loop) and assign each character of the string
  89. >individually and manually add the '\0' at the end. This seems
  90. >extremely laborious and I'm sure it can't be the best way. (Also it
  91. >may give similar "unexpected results"?)
  92.  
  93. You could do:
  94.  
  95.     char *string1[30];
  96.     string1[0] = "Test string";
  97.     string1[1] = "Another test string";
  98.  
  99. and so forth.
  100.  
  101.  
  102. You assign to a string using the standard string functions. If you know that
  103. the destination operand has enough storage, you can use:
  104.  
  105.     strcpy(dest, source);
  106.  
  107. Source can be a string literal:
  108.  
  109.     char mystring[50];
  110.  
  111.     strcpy(mystring, "Hello, world!");
  112.  
  113. When you are not sure how long the source string is, you use strncpy(), which
  114. takes an additional count argument. The nasty thing is that strncpy() will not
  115. append a null character to the destination, but copy characters right up to the
  116. end. So you have a few possibilities:
  117.  
  118. 1.    Store zeros into the destination, then specify a size that is one
  119.     less than the actual size:
  120.  
  121.     char mystring[50];
  122.  
  123.     memset(mystring, 0, sizeof(mystring));    /* store zeros    */
  124.  
  125.     strncpy(mystring, mystery_string, sizeof(mystring));
  126.  
  127. 2.    Store a single zero to the last position before or after doing the
  128.     copy:
  129.  
  130.  
  131.     char mystring[50];
  132.  
  133.     strncpy(mystring, mystery_string, sizeof(mystring) - 1);
  134.  
  135.     mystring[sizeof(mystring)-1] = 0;
  136.  
  137. It would be nice if strncpy() did this for you, wouldn't it? But it's
  138. standardized to work a certain way.
  139. -- 
  140.  
  141.